#include<iostream>
using namespace std;

#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>

//2023.3.6 更新，父进程在等待期间执行其他任务

void loadData()
{
  cout << "执行加载数据的函数" << endl;
}

void netCon()
{
  cout << "执行网络连接的函数" << endl;
}

void clearDate()
{
  cout << "执行数据清理函数" << endl;
}

#define TASK_MAX 10

typedef void (*fun_c)();  //函数指针
fun_c other_task[TASK_MAX] = { 0 }; //函数指针数组

int LoadTask(fun_c func)
{
  int i = 0;
  for(; i < TASK_MAX; i++)
  {
    if(other_task[i] == NULL) break;
  }

  if(i == TASK_MAX) return -1;  //此时函数指针数组已满，无法再装载
  
  other_task[i] = func;
  return 0; //装载成功
}

void InitTask()
{
  for(int i = 0; i < TASK_MAX; i++)
    other_task[i] = NULL;

  LoadTask(loadData);
  LoadTask(netCon);
  LoadTask(clearDate);
}

void RunTask()
{
  int i = 0;
  while(other_task[i] && i < TASK_MAX)
    other_task[i++]();
}

int main()
{
//  fork();
//  fork() && fork() || fork();
//  fork();
//  sleep(100);
   
  pid_t id = fork();
  if(id == 0)
  {
    int n = 5;
    while(n)
    {
        cout << "我是子进程，我还在运行，剩余运行时间:" << n << " 我的是PID是:" << getpid() << " PPID是:" << getppid() << endl;
        n--;
        sleep(1);
    }

    exit(120);
  }

  //pid_t ret_id = wait(NULL);
  int val = 0;
  //pid_t ret_id = waitpid(id, &val, 0);


  InitTask();

  while(1)
  {

    pid_t ret_id = waitpid(id, &val, WNOHANG);

    if(ret_id < 0)
    {
      perror("waitpid errar!");
      exit(-1);
    }
    else if(ret_id == 0)
    {
      cout << "子进程还在运行" << endl;
      RunTask();
      sleep(1);
    }
    else if(WIFEXITED(val))
    {

      cout << "我是父进程，PID:" << getpid() << " PPID:" << getppid() << " status:" << val << endl;
      cout << "exit code:" << WEXITSTATUS(val) << endl;
      sleep(3);
    }
    else 
    {
      cout << "我是父进程，PID:" << getpid() << " PPID:" << getppid() << " status:" << val << endl;
      cout << "exit signal:" << (val & 0x7F) << endl;
      cout << "code dump:" << ((val >> 7) & 1) << endl;
      sleep(3);
    }
  }

  return 0;
}
